<template>
    <div>
        <div class="form">
            <el-form :inline="true" :model="searchData" class="demo-form-inline">
                <el-form-item>
                    <el-input class="input" v-model="searchData.title" placeholder="请输入优惠劵名称" clearable />
                </el-form-item>
                <el-form-item>
                    <el-select v-model="searchData.type" class="m-2" placeholder="请选择优惠劵类型" size="large" clearable>
                        <el-option v-for="item in couponTypeMa" :key="item.value" :label="item.name"
                            :value="item.value" />
                    </el-select>
                </el-form-item>
                <el-form-item>
                    <el-select v-model="searchData.status" class="m-2" placeholder="请选择优惠劵状态" size="large" clearable>
                        <el-option v-for="item in couponStatusMa" :key="item.value" :label="item.name"
                            :value="item.value" />
                    </el-select>
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" :icon="Search" @click="handelSearch">查找</el-button>
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" :icon="Plus" @click="handelAdd">添加</el-button>
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" :icon="Download" @click="handleExport">当前页导出</el-button>
                </el-form-item>
            </el-form>
        </div>
        <div>
            <el-table :data="tableData" id="table" style="width: 100%" border
                :header-cell-style="{ 'text-align': 'center' }" :cell-style="{ 'text-align': 'center' }">
                <el-table-column label="优惠劵ID" prop="id" sortable />
                <el-table-column label="优惠劵名称" prop="title" />
                <el-table-column label="优惠劵类型" prop="type">
                    <template #default="scope">
                        {{ scope.row.type == 1 ? '满减劵' : '立减劵' }}
                    </template>
                </el-table-column>
                <el-table-column label="介绍" prop="description" />
                <el-table-column label="优惠劵数量" prop="total" />
                <el-table-column label="剩余数量" prop="surplus" />
                <el-table-column label="每人限领" prop="limit" />
                <el-table-column label="满减金额">
                    <template #default="scope">
                        减免{{ scope.row.discount }}元
                    </template>
                </el-table-column>
                <el-table-column label="最低消费">
                    <template #default="scope">
                        满{{ scope.row.min }}元可用
                    </template>
                </el-table-column>
                <el-table-column label="状态" width="120">
                    <template #default="scope">
                        <el-tag :type="scope.row.status == 1 ? '' : 'danger'">
                            {{ handelSataus(scope.row.status) }}
                        </el-tag>
                    </template>
                </el-table-column>
                <el-table-column label="使用类目名称" width="120">
                    <template #default="scope">
                        <el-tag>{{ scope.row.categoryTitle ? scope.row.categoryTitle : '全部类目' }}</el-tag>
                    </template>
                </el-table-column>
                <el-table-column label="使用类目ID" prop="categoryId" />
                <el-table-column label="领劵相对天数" prop="days">
                    <template #default="scope">
                        {{ scope.row.days ? scope.row.days : '无' }}
                    </template>
                </el-table-column>
                <el-table-column label="领劵开始时间" prop="gmtStart">
                    <template #default="scope">
                        {{ scope.row.gmtStart ? new Date(scope.row.gmtStart).friendTime(2) : '无' }}
                    </template>
                </el-table-column>
                <el-table-column label="领劵结束时间" prop="gmtEnd">
                    <template #default="scope">
                        {{ scope.row.gmtStart ? new Date(scope.row.gmtEnd).friendTime(2).slice(0, 16) : '无' }}
                    </template>
                </el-table-column>
                <el-table-column label="操作" width="180">
                    <template #default="scope">
                        <el-button size="small" type="primary" v-if="scope.row.status == -1">已过期</el-button>
                        <el-button size="small" v-else :type='scope.row.status == 0 ? "primary" : "danger"'
                            @click="changeStatus(scope.row)">
                            {{ scope.row.status == 0 ? '激活' : '冻结' }}
                        </el-button>
                        <el-button size="small" type="info" @click="handleSee(scope.row)">查看</el-button>
                    </template>
                </el-table-column>
            </el-table>
        </div>
        <div>
            <Pagetion v-bind="pagetio" @page-change="pageChange"></Pagetion>
        </div>
        <div>
            <el-backtop target=".el-main" :right="100" :bottom="100" ref="backTop" :visibility-height="20" />
        </div>

        <div>
            <el-dialog v-model="dialogFormVisible" :title="title" :destroy-on-close="true">
                <el-form ref="ruleFormRef" :model="ruleForm" status-icon :rules="rules" label-width="120px"
                    class="demo-ruleForm" :disabled="title == '查看'">
                    <el-form-item label="优惠劵名称" prop="title">
                        <el-input v-model="ruleForm.title" autocomplete="off" placeholder="请输入优惠劵名称" />
                    </el-form-item>
                    <el-form-item label="优惠劵类型" prop="type">
                        <el-select v-model="ruleForm.type" class="m-2" placeholder="请选择优惠劵类型" size="large" clearable>
                            <el-option v-for="item in couponTypeMa.slice(0, 2)" :key="item.value" :label="item.name"
                                :value="item.value" />
                        </el-select>
                    </el-form-item>
                    <el-form-item label="介绍">
                        <el-input v-model.number="ruleForm.description" />
                    </el-form-item>
                    <el-form-item label="优惠劵数量" prop="total">
                        <el-input v-model="ruleForm.total" placeholder="请输入优惠劵数量">
                            <template #append>张</template>
                        </el-input>
                    </el-form-item>
                    <el-form-item label="每人限领" prop="limit">
                        <el-input v-model="ruleForm.limit" placeholder="请输入限领数量">
                            <template #append>张</template>
                        </el-input>
                    </el-form-item>
                    <el-form-item label="优惠金额" prop="discount">
                        <el-input v-model="ruleForm.discount" placeholder="请输入优惠金额">
                            <template #append>元</template>
                        </el-input>
                    </el-form-item>
                    <el-form-item label="最低消费" prop="min">
                        <el-input v-model="ruleForm.min" placeholder="请输入最低消费金额">
                            <template #append>元</template>
                        </el-input>
                    </el-form-item>
                    <el-form-item label="优惠劵状态" prop="status">
                        <el-select v-model="ruleForm.status" class="m-2" placeholder="请选择优惠劵状态" size="large" clearable>
                            <el-option v-for="item in couponStatusMa.slice(0, 3)" :key="item.value" :label="item.name"
                                :value="item.value" />
                        </el-select>
                    </el-form-item>
                    <el-form-item label="有效期">
                        <el-radio-group v-model="validity" size="large">
                            <el-radio-button :label="0" @change="clearDateTime">领劵相对天数</el-radio-button>
                            <el-radio-button :label="1" @change="ruleForm.days = undefined">领劵绝对时间</el-radio-button>
                        </el-radio-group>
                    </el-form-item>
                    <el-form-item :prop="validity == 0 ? 'days' : 'gmtEnd'">
                        <div v-if="validity == 0">
                            <el-input v-model="ruleForm.days">
                                <template #append>天</template>
                            </el-input>
                        </div>
                        <div v-else>
                            <el-date-picker v-model="ruleForm.gmtStart" type="datetime" placeholder="请选择时间日期"
                                format="YYYY/MM/DD hh:mm:ss" value-format="x" />
                            <span style="margin: 0 5px;">至</span>
                            <el-date-picker v-model="ruleForm.gmtEnd" type="datetime" placeholder="请选择时间日期"
                                format="YYYY/MM/DD hh:mm:ss" value-format="x" />
                        </div>
                    </el-form-item>
                    <el-form-item label="商品限制范围">
                        <el-radio-group v-model="limits" size="large">
                            <el-radio-button :label="0" @change="ruleForm.categoryId = undefined">全场通用</el-radio-button>
                            <el-radio-button :label="1">指定分类</el-radio-button>
                        </el-radio-group>
                    </el-form-item>
                    <el-form-item label="优惠类目" v-if="limits == 1">
                        <el-cascader :options="categoryData" v-model="ruleForm.categoryId"
                            :props="{ checkStrictly: true, children: 'childrenList', value: 'id', label: 'title', emitPath: false }" />
                    </el-form-item>
                </el-form>
                <template #footer>
                    <span class="dialog-footer">
                        <el-button @click="dialogFormVisible = false">取消</el-button>
                        <el-button type="primary" v-if="title == '创建'" @click="submitForm(ruleFormRef)">
                            确定
                        </el-button>
                    </span>
                </template>
            </el-dialog>
        </div>
    </div>
</template>

<script lang="ts" setup>
import { ref, reactive, nextTick } from 'vue'
import { Search, Plus, Download } from '@element-plus/icons-vue'
import { ClassPagination, ClassCouponAdd } from "#/index";
import { post } from '@/http/request';
import { ElMessage } from 'element-plus';
import Pagetion from "@/components/pagetion/Pagetion.vue";//分页
import "@/utils/DateFormatter";//友好日期
import type { FormInstance } from 'element-plus'
import * as XLSX from "xlsx";//引入Excel表格导出

const backTop = ref()
const pagetio = reactive(new ClassPagination())//实例化分页数据
const tableData = ref<TypeCoupon[]>([])//接收表格数据
const dialogFormVisible = ref(false)//弹窗是否显示
const validity = ref(0)//有效期切换按钮
const limits = ref(0)//商品限制范围切换按钮
const categoryData = ref([])//类目数据
const title = ref('')//弹窗标题
const ruleFormRef = ref<FormInstance>()
const ruleForm = reactive(new ClassCouponAdd())//实例化添加传递的数据
const form = reactive({ ...ruleForm })


// 优惠劵数量  
const validateTotal = (rule: Object, value: number, callback: Function) => {
    if (value == 0) {
        callback(new Error('数量必须大于0'))
    } else if (isNaN(value)) {
        callback(new Error("请输入数字"))
    } else if (value - 0 < ruleForm.limit - 0) {
        callback(new Error("优惠卷数量必须大于每人限领"))
    }
    callback()
}

// 每人限领
const validateLimit = (rule: Object, value: number, callback: Function) => {
    if (value == 0) {
        callback(new Error('数量必须大于0'))
    } else if (isNaN(value)) {
        callback(new Error("数量必须是数字"))
    } else if (value - 0 > ruleForm.total + 0) {
        callback(new Error("每人限领不能大于优惠卷数量"))
    }
    callback()
}

//优惠金额验证
const validateDiscount = (rule: Object, value: number, callback: Function) => {
    if (value == 0) {
        callback(new Error('数量必须大于0'))
    } else if (isNaN(value)) {
        callback(new Error("请输入数字"))
    } else if (ruleForm.min < value) {
        callback(new Error("优惠金额必须大于最低消费"))
    }
    callback()
}

// 最低消费
const validateMin = (rule: Object, value: number, callback: Function) => {
    if (isNaN(value)) {
        callback(new Error("请输入数字"))
    } else if (ruleForm.discount > ruleForm.min) {
        callback(new Error("最低消费不能低于优惠金额"))
    } else {
        callback()
    }
}

//领券相对天数
const validateDays = (rule: object, value: number, callback: Function) => {
    if (isNaN(value)) {
        return callback(new Error('请输入正确天数'))
    } else {
        callback()
    }
}

//领券绝对时间验证
const validateGmtEnd = (rule: object, value: string, callback: Function) => {
    if (ruleForm.gmtStart && ruleForm.gmtStart > value) {
        return callback(new Error('结束时间不能小于开始时间'))
    } else {
        callback()
    }
}

// 弹窗表单验证规则
const rules = reactive({
    title: [//优惠劵名称
        { required: true, message: '请输入优惠劵名称', trigger: 'blur' },
    ],
    type: [//优惠劵类型
        { required: true, message: '请选择优惠劵类型', trigger: 'change' },
    ],
    total: [//优惠劵数量
        { validator: validateTotal, trigger: 'blur' },
        { required: true, message: '请填写数量', trigger: 'blur' },
    ],
    limit: [//每人限领
        { validator: validateLimit, trigger: 'blur' },
        { required: true, message: '请填写数量', trigger: 'blur' },
    ],
    discount: [//优惠金额
        { validator: validateDiscount, trigger: 'blur' },
        { required: true, message: '请填写金额', trigger: 'blur' },
    ],
    min: [//最低消费
        { validator: validateMin, trigger: 'blur' },
        { required: true, message: '请填写金额', trigger: 'blur' },
    ],
    status: [//优惠劵类型
        { required: true, message: '请选择优惠劵状态', trigger: 'change' },
    ],
    days: [//相对天数
        { validator: validateDays, trigger: 'blur' },
    ],
    gmtEnd: [//结束时间
        { validator: validateGmtEnd, trigger: 'change' },
    ],
})

// 优惠劵状态
const couponStatusMa: TypeSelect[] = reactive([
    { value: 0, name: "下架" },
    { value: 1, name: "正常" },
    { value: -1, name: "已过期" },
    { value: "", name: "全部" },
]);

// 优惠劵类型
const couponTypeMa: TypeSelect[] = [
    { value: 1, name: "满减劵" },
    { value: 2, name: "立减劵" },
    { value: "", name: "全部" },
];

// 初始化数据传递的参数
let params = reactive({
    _gp: "admin.coupon",
    _mt: "list",
    title: "",
    type: undefined,
    status: undefined,
    pageNo: pagetio.pageNo,
    limit: pagetio.pageSize,
})

// 搜索需要的参数
let searchData = reactive({
    title: "",
    type: undefined,
    status: undefined,
})

// 初始化数据
function loadInit() {
    post(params).then(res => {
        console.log(res);
        let { data, errmsg, errno } = res
        data.items.forEach((item: TypeCoupon) => {
            if (item.gmtEnd && item.gmtEnd < +new Date()) {
                item.status = -1
            }
        });
        if (200 == errno) {
            tableData.value = data.items
            pagetio.total = data.total

        } else {
            ElMessage.error(errmsg)
        }
    })
}
loadInit()

// 状态处理
function handelSataus(status: number) {
    if (status == 0) {
        return '下架'
    } else if (status == 1) {
        return '正常'
    } else if (status < 0) {
        return '已过期'
    }
}

// 搜索
function handelSearch() {
    params.title = searchData.title
    params.type = searchData.type
    params.status = searchData.status
    loadInit()
}

// 修改优惠劵状态
function changeStatus(row: TypeCoupon) {
    let statusParams = reactive({
        _gp: "admin.coupon",
        _mt: "updateCouponStatus",
        id: row.id,
        status: row.status == 0 ? 1 : 0
    })
    post(statusParams).then(res => {
        console.log(res);
        let { errmsg, errno } = res
        if (200 == errno) {
            ElMessage.success("修改状态成功")
            loadInit()
        } else {
            ElMessage.error(errmsg)
        }
    })
}

//  添加
function handelAdd() {
    Object.assign(ruleForm, form)
    title.value = "创建"
    dialogFormVisible.value = true
}

// 添加请求
const submitForm = (formEl: FormInstance | undefined) => {
    if (!formEl) return
    formEl.validate((valid) => {
        if (valid) {
            let addParams = reactive({
                _gp: "admin.coupon",
                _mt: "create",
                ...ruleForm
            })
            post(addParams).then(res => {
                console.log(res);
                let { errmsg, errno } = res
                if (200 == errno) {
                    dialogFormVisible.value = false
                    ElMessage.success("添加成功")
                    loadInit()
                } else {
                    ElMessage.error(errmsg)
                }
            })
        } else {
            return false
        }
    })
}

// 查看
const handleSee = (row: TypeCoupon) => {
    // console.log(row);
    Object.assign(ruleForm, form)
    title.value = "查看"
    validity.value = row.gmtStart ? 1 : 0
    limits.value = row.categoryTitle ? 1 : 0
    Object.assign(ruleForm, row)
    dialogFormVisible.value = true
}

// 清空绝对时间
function clearDateTime() {
    ruleForm.gmtStart = ""
    ruleForm.gmtEnd = ""
}

// 导出当前页
function handleExport() {
    let workbook = XLSX.utils.table_to_book(document.getElementById("table")); //在table上定义一个id
    try {
        XLSX.writeFile(workbook, "表格信息.xlsx");
        ElMessage.success("导出成功!");
    } catch (e) {
        ElMessage.error("导出失败!");
    }
}

// 请求弹窗类目选择数据
function popOption() {
    let data = {
        _gp: 'admin.category',
        _mt: 'categoryTree'
    }
    post(data).then(res => {
        console.log(res);
        let { data, errno, errmsg } = res
        if (200 == errno) {
            categoryData.value = data
        } else {
            ElMessage.error(errmsg)
        }
    })
}
popOption()

// 分页组件子传父自定义事件
const pageChange = (e: TypePage) => {
    params.pageNo = e._pageNo
    params.limit = e._pageSize
    loadInit()
    nextTick(() => {
        backTop.value.$el.click?.()
    })
}
</script>

<style lang="less" scoped>
.el-form-item {
    margin-right: 10px !important;
}

.input {
    height: 40px !important;
}

.el-select {
    width: 200px;
}

.el-input {
    width: 200px;
}


.el-dialog__body {
    .el-form-item {
        margin-bottom: 20px !important;
    }

    .el-input {
        width: 500px !important;
    }
}
</style>